package com.factory.code.lib.database;


import com.factory.code.common.helper.StringHelper;
import com.factory.code.controller.param.ConnectionParam;
import com.factory.code.lib.database.model.DatebaseTypeAndDriverModel;
import com.factory.code.repository.ProjectRepository;
import com.factory.code.repository.ent.ProjectENT;
import org.apache.commons.lang3.NotImplementedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Component
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class DatabaseBehaviorFactory {

    @Autowired
    private ProjectRepository projectRepository;

    private final Map<String, DatabaseBehavior> databaseBehaviorMap;

    private List<DatebaseTypeAndDriverModel> typeAndDriverList;


    public DatabaseBehaviorFactory(Map<String, DatabaseBehavior> databaseBehaviorMap) {
        typeAndDriverList = new ArrayList<>();
        for (String key : databaseBehaviorMap.keySet()) {
            DatabaseBehavior databaseBehavior = databaseBehaviorMap.get(key);
            String dbType = databaseBehavior.getDbType();
            List<String> dbDriver = databaseBehavior.getDbDriver();
            typeAndDriverList.add(new DatebaseTypeAndDriverModel(dbType, dbDriver));
        }
        this.databaseBehaviorMap = databaseBehaviorMap;
    }

    public DatabaseBehavior getDatabaseBehavior(Integer projectId) {
        ProjectENT projectENT = projectRepository.getById(projectId);

        String beanName = StringHelper.lowerFirstCase(projectENT.getDbType()).concat("DatabaseBehavior");
        if (!databaseBehaviorMap.containsKey(beanName)) {
            throw new NotImplementedException(String.format("not support:%s", beanName));
        }
        ConnectionParam connectionParam = new ConnectionParam();
        connectionParam.setDbType(projectENT.getDbType());
        connectionParam.setDbDriver(projectENT.getDbDriver());
        connectionParam.setDbUrl(projectENT.getDbUrl());
        connectionParam.setDbUsername(projectENT.getDbUsername());
        connectionParam.setDbPassword(projectENT.getDbPassword());
        DatabaseBehavior databaseBehavior = databaseBehaviorMap.get(beanName);
        databaseBehavior.initialize(connectionParam);
        return databaseBehavior;
    }

    public List<DatebaseTypeAndDriverModel> getTypeAndDriverList() {
        return typeAndDriverList;
    }
}
